/*******************************************************************************************
 *      @name   bemfa.c
 *      @brief  获取天气发送巴法云
 *      @date   2025/02/21
 *      @author cecelmx@126.com
 *      @note
 *              1.巴法云支持TCP协议，TCP协议的端口是8344，域名是bemfa.com
 *
 *      @version  xx.xx.xx   主版本号.次版本号.修正版本号
 *
 *      CopyRight (c)   2024-2025   Your Name     All Right Reserved
 *
 * ****************************************************************************************/

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/udp.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <netdb.h>
#include <sys/ipc.h>
#include <sys/msg.h>

#define BUFSIZE 512

#define UID "124c27fd799448be89c420c70b53a80e" // 用户密钥

#define TOPIC "temp004" // 主题名称

typedef struct weather
{
    int temp;
} weather_t, *weather_p;

typedef struct msgbuf
{
    long mtype;
    weather_t weather_data;
} msg_t, *msg_p;

int queue_id = 0;

int temp = 0;

/**************************************************************************
 * @name: create_queue
 * @brief: 创建消息队列
 * @note: None
 * @retval: None
 **************************************************************************/
void create_queue(void)
{
    queue_id = msgget(ftok(".", 1), IPC_CREAT | 0666);
    if (queue_id == -1)
    {
        fprintf(stderr, "创建队列失败,error=%d,%s\n", errno, strerror(errno));
    }
    printf("创建的队列ID:%d\n", queue_id);
}

/**************************************************************************
 * @name: get_msg
 * @brief: 获取消息队列中的队列
 * @note: None
 * @retval: None
 **************************************************************************/
void get_msg(void)
{
    msg_p msg_data = (msg_p)calloc(1, sizeof(msg_t));
    msgrcv(queue_id, msg_data, sizeof(weather_t), 1, IPC_NOWAIT);
    if (msg_data->weather_data.temp != 0)
    {
        printf("temp:??%d\n", msg_data->weather_data.temp);
        temp = msg_data->weather_data.temp;
    }

    free(msg_data);
}

int main(int argc, char **argv)
{

    char recvbuf[BUFSIZE] = {0};
    create_queue();
    // 1.创建TCP套接字
    int tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (-1 == tcp_socket)
    {
        fprintf(stderr, "create tcp socket error,%s\n", strerror(errno));
        exit(-1);
    }

    // 2.向服务器发起连接请求
    struct sockaddr_in dest = {0};                      // IPv4地址格式的实例
    dest.sin_family = AF_INET;                          // IPv4协议族
    dest.sin_port = htons(8344);                        // 目标端口，需要转换为网络字节序
    dest.sin_addr.s_addr = inet_addr("119.91.109.180"); // 目标地址，需要转换为网络字节序

    if (-1 == connect(tcp_socket, (struct sockaddr *)&dest, sizeof(dest)))
    {
        fprintf(stderr, "connect error,%s\n", strerror(errno));
        exit(-2);
    }

    printf("connect ok\n");

    // 3.连接成功后，可以订阅服务器的主题，需要构造消息内容
    char msgbuf[BUFSIZE] = {0};
    sprintf(msgbuf, "cmd=1&uid=%s&topic=%s\r\n", UID, TOPIC);

    send(tcp_socket, msgbuf, strlen(msgbuf), 0); // 向巴法云服务器发送订阅主题的消息

    printf("send ok\n");

    // 接收服务器下发的订阅状态
    recv(tcp_socket, recvbuf, sizeof(recvbuf), 0); // 读取数据，默认会阻塞
    printf("recv data from bemfa server is %s\n", recvbuf);
    send(tcp_socket, msgbuf, strlen(msgbuf), 0); // 向巴法云服务器发送订阅主题的消息
    while (1)
    {
        // 发布消息
        memset(msgbuf, 0, BUFSIZE);
        get_msg();
        sprintf(msgbuf, "cmd=2&uid=%s&topic=%s&msg=%d\r\n", UID, TOPIC, temp);
        send(tcp_socket, msgbuf, strlen(msgbuf), 0); // 向巴法云服务器发送订阅主题的消息
        sleep(1);
    }

    return 0;
}
